package cn.itcast.service.impl;

import cn.hutool.core.util.ObjectUtil;
import cn.itcast.constant.MessageConstant;
import cn.itcast.dao.OrderDao;
import cn.itcast.dao.OrderSettingDao;
import cn.itcast.entity.OrderQueryPageBean;
import cn.itcast.entity.PageResult;
import cn.itcast.entity.Result;
import cn.itcast.pojo.Member;
import cn.itcast.pojo.Order;
import cn.itcast.pojo.OrderSetting;
import cn.itcast.service.MemberService;
import cn.itcast.service.OrderService;
import cn.itcast.service.OrderSettingService;
import cn.itcast.util.IdWorker;
import cn.itcast.utils.DateUtils;
import com.alibaba.dubbo.config.annotation.Service;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;
import java.util.Map;


@Service(version = "1.0.0")
public class OrderServiceImpl implements OrderService {

    @Autowired
    private OrderDao orderDao;


    @Autowired
    private OrderSettingDao orderSettingDao;

    @Autowired
    private OrderSettingService orderSettingService;

    @Autowired
    private MemberService memberService;

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    /**
     * 预约功能
     *
     * @param order 用户填写的预约信息
     * @return
     */
    @Override
    public Result submit(Order order) {

        // 1. 如果选择的日期没有设置 预约不能进行预约
        Date date = order.getOrderDate();
        String formatDate = null;
        try {
            formatDate = DateUtils.parseDate2String(date);
        } catch (Exception e) {
            e.printStackTrace();
        }

        // 到数据库中去查询此日期是否可以预约
        OrderSetting orderSetting = findOrderSettingbyDate(formatDate);
        if (ObjectUtil.isEmpty(orderSetting)) {
            return new Result(false, MessageConstant.SELECTED_DATE_CANNOT_ORDER);
        }


        // 2.判断人数是否已经预约满
        if (orderSetting.getReservations() >= orderSetting.getNumber()) {
            return new Result(false, MessageConstant.ORDER_FULL);
        }


        // 3.如果当前用户已经预约过该体检套餐, 不允许预约  (身份证相同即为同一用户)
        String idCard = order.getIdCard();
        boolean result = queryOrderByidCardAndDate(idCard, formatDate);
        if (result) {
            // 不为空说明此用户今天已经预约过了
            return new Result(false, MessageConstant.HAS_ORDERED);
        }

        // 4. 预约成功后添加用户到数据库中
        // 首先先查询出用户的会员信息
        Member member = memberService.queryById(order.getMemberId());
        // 定义一个order对象在表中的id
        String orderId = new IdWorker().nextId() + "";
        order.setId(orderId);

//        order.setMemberId(member.getId());   控制前层已经添加
//        order.setOrderType(Order.ORDERTYPE_WEIXIN);   控制前层已经添加
        order.setOrderStatus(0);
        order.setArrival(0);
        order.setBirthday(member.getBirthday());
        order.setMarried(Short.valueOf("0"));
        order.setSex(member.getSex());
        order.setPayStatus(0);

        orderDao.submit(order);
        // 预约成功后更新数据库 t_ordersetting 表中的预约人数信息
        int count = updateOrderSettingReservations(orderSetting.getReservations() + 1, formatDate);
        // 返回 并将orderId也返回
        return count > 0 ? new Result(true, MessageConstant.ORDER_SUCCESS, orderId) : new Result(false, MessageConstant.ORDER_FAIL);
    }

    /**
     * 根据id查询出用户订单信息
     * private OrderSettingDao orderSettingDao;
     * <p>
     * /**
     * 添加保存预约信息
     * order添加一笔记录 要查询该用户的预约时间 通过预约时间 查询当天的预约人数是否已满
     *
     * @param order
     */
    @Transactional
    @Override
    public String add(Order order) {

        //给order设置一个主键
        order.setId(new IdWorker().nextId() + "");

        //获得添加人的预约时间
        Date orderDate = order.getOrderDate();

        //如果修改预约人数成功
        if (orderSettingDao.updateByTimeAndNumber(orderDate) > 0) {
            //再进行添加
            orderDao.add(order);
            return "添加成功";
        } else {
            return "预约满了";
        }

    }


    /**
     * 根据id查询个人预约详情
     *
     * @param id
     * @return
     */
    @Override
    public Order findById(String id) {
        return orderDao.findByid(id);
    }

    /**
     * 根据id查询出 orderVo对象 就是支付页面需要展示的数据
     * @param id
     * @return
     */
//    @Override
//    public OrderVo queryOrderVoByOrderId(String id) {
//        return orderDao.queryOrderVoByOrderId(id);
//    }

    /**
     * 根据用户的会员id查询出该用户的所有订单
     *
     * @param memberId
     * @return
     */
    @Override
    public List<Order> findUserAll(Integer memberId) {
        return orderDao.findUserAll(memberId);

    }


    /**
     * 编辑预约信息  用户修改预约日期修改为已经预约满的日期 所以也要做判断
     *
     * @param order
     */
    @Transactional
    @Override
    public String update(Order order) {

        //获得修改人的预约时间
        Date orderDate = order.getOrderDate();

        //先将orderSetting预约人数+1 加成功
        if (orderSettingDao.updateByTimeAndNumber(orderDate) > 0) {
            //再进行修改
            orderDao.update(order);

            return "修改成功";

        } else {

            return "预约满了";
        }

    }


    /**
     * 更新预约人数
     *
     * @param reservations
     * @param formatDate
     * @return
     */
    private int updateOrderSettingReservations(int reservations, String formatDate) {

        return orderSettingService.updateReservations(reservations, formatDate);
    }

        @Override
        public List<Order> findAll () {
            return orderDao.findAll();

        }


        /**
         * 查询用户是否在此日期已经预约过
         * @param idCard      身份证
         * @param formatDate  预约日期
         * @return
         */
        private boolean queryOrderByidCardAndDate (String idCard, String formatDate){
            return ObjectUtil.isNotEmpty(orderDao.queryOrderByidCardAndDate(idCard, formatDate));
        }


        /**
         * 查询挂号时间的方法
         *
         * @param date
         * @return
         */
        private OrderSetting findOrderSettingbyDate (String date){
            OrderSetting orderSetting = orderSettingService.queryOrderDate(date);
            return orderSetting;
        }

        @Override
        public PageResult pageQuery (OrderQueryPageBean orderQueryPageBean){

            //没有查询条件只进行分页查询
            PageHelper.startPage(orderQueryPageBean.getCurrentPage(), orderQueryPageBean.getPageSize());
            Page<Order> page = orderDao.selectByCondition(orderQueryPageBean);
            return new PageResult(page.getTotal(), page.getResult());

        }

        /**
         * 修改到诊
         * @param row
         */
        @Override
        public void updateArrival (Order order){
            orderDao.updateArrival(order.getId());
        }

    //今日预约数
    @Override
    public Integer findOrderCountByDate(String today) {
        return this.orderDao.findOrderCountByDate(today);
    }
    //今日到诊数
    @Override
    public Integer findVisitsCountByDate(String today) {
        return this.orderDao.findVisitsCountByDate(today);
    }
    //本周的预约数
    @Override
    public Integer findOrderCountWeekAfterDate(String thisWeekMonday) {
        return this.orderDao.findOrderCountWeekAfterDate(thisWeekMonday);
    }
    //本周到诊数
    @Override
    public Integer findVisitsCountWeekAfterDate(String thisWeekMonday) {
        return this.orderDao.findVisitsCountWeekAfterDate(thisWeekMonday);
    }
    //本月预约数
    @Override
    public Integer findOrderCountMonthAfterDate(String firstDay4ThisMonth) {
        return this.orderDao.findOrderCountMonthAfterDate(firstDay4ThisMonth);
    }
    //本月到诊数
    @Override
    public Integer findVisitsCountMonthAfterDate(String firstDay4ThisMonth) {
        return this.orderDao.findVisitsCountMonthAfterDate(firstDay4ThisMonth);
    }

    @Override
    public List<Map> findhotSetmeal() {
        return this.orderDao.findhotSetmeal();
    }
}


